
`timescale 1 ns / 1 ps

	module axis_dma_sender_v1_0 #
	(
		// Users to add parameters here

		// User parameters ends
		// Do not modify the parameters beyond this line


		// Parameters of Axi Slave Bus Interface S00_AXI
		parameter integer C_S00_AXI_DATA_WIDTH	= 32,
		parameter integer C_S00_AXI_ADDR_WIDTH	= 4,
		parameter integer ENABLE_EDIT = 1,
		parameter integer TRANS_MAX_NUM = 1024,
		parameter integer TRANS_START_POSTION = 12,
		parameter integer TUSER_WIDTH = 2
	)
	(
		// Users to add ports here

		// User ports ends
		// Do not modify the ports beyond this line


		// Ports of Axi Slave Bus Interface S00_AXI
		input wire  s00_axi_aclk,
		input wire  s00_axi_aresetn,
		input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr,
		input wire [2 : 0] s00_axi_awprot,
		input wire  s00_axi_awvalid,
		output wire  s00_axi_awready,
		input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata,
		input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb,
		input wire  s00_axi_wvalid,
		output wire  s00_axi_wready,
		output wire [1 : 0] s00_axi_bresp,
		output wire  s00_axi_bvalid,
		input wire  s00_axi_bready,
		input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr,
		input wire [2 : 0] s00_axi_arprot,
		input wire  s00_axi_arvalid,
		output wire  s00_axi_arready,
		output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata,
		output wire [1 : 0] s00_axi_rresp,
		output wire  s00_axi_rvalid,
		input wire  s00_axi_rready,

		input wire      axis_aclk,
		input wire      axis_aresetn,

		input wire[31:0] s_axis_tdata,
		input wire[3:0]  s_axis_tkeep,
		input wire	     s_axis_tvalid,
		output wire      s_axis_tready,
	    input  wire[TUSER_WIDTH - 1:0] s_axis_tuser,

		output wire[31:0] m_axis_tdata,
		output wire		  m_axis_tvalid,
		input  wire       m_axis_tready,
		output wire       m_axis_tlast,
		output wire[3:0]  m_axis_tkeep,
		output wire[TUSER_WIDTH - 1:0] m_axis_tuser,
		output wire[15:0] trans_num,
		input wire 	      enable
	);

	wire[31:0] reg0_o;
	wire[31:0] reg0_i;
	reg[31:0] data_num;
	reg[31:0] reg0;
	wire[31:0] sp;
	wire       valid;
	wire 	   ready;

	assign m_axis_tuser = s_axis_tuser;
	assign m_axis_tvalid = ENABLE_EDIT ? (data_num[31] ? valid : 1'b0) : (enable ? valid : 1'b0);
	assign ready = ENABLE_EDIT ? (data_num[31] ? m_axis_tready : 1'b0) : (enable ? m_axis_tready : 1'b0);		
// Instantiation of Axi Bus Interface S00_AXI
	axis_dma_sender_v1_0_S00_AXI # ( 
		.C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
		.C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH),
		.MAX_NUM(TRANS_MAX_NUM)
	) axis_dma_sender_v1_0_S00_AXI_inst (
		.reg0_out(reg0_o),
		.S_AXI_ACLK(s00_axi_aclk),
		.S_AXI_ARESETN(s00_axi_aresetn),
		.S_AXI_AWADDR(s00_axi_awaddr),
		.S_AXI_AWPROT(s00_axi_awprot),
		.S_AXI_AWVALID(s00_axi_awvalid),
		.S_AXI_AWREADY(s00_axi_awready),
		.S_AXI_WDATA(s00_axi_wdata),
		.S_AXI_WSTRB(s00_axi_wstrb),
		.S_AXI_WVALID(s00_axi_wvalid),
		.S_AXI_WREADY(s00_axi_wready),
		.S_AXI_BRESP(s00_axi_bresp),
		.S_AXI_BVALID(s00_axi_bvalid),
		.S_AXI_BREADY(s00_axi_bready),
		.S_AXI_ARADDR(s00_axi_araddr),
		.S_AXI_ARPROT(s00_axi_arprot),
		.S_AXI_ARVALID(s00_axi_arvalid),
		.S_AXI_ARREADY(s00_axi_arready),
		.S_AXI_RDATA(s00_axi_rdata),
		.S_AXI_RRESP(s00_axi_rresp),
		.S_AXI_RVALID(s00_axi_rvalid),
		.S_AXI_RREADY(s00_axi_rready)
	);

	dma_sender u_dma_sender(
		.readed_data_count(trans_num),
		.clk       (axis_aclk       ),
		.rst_n     (axis_aresetn    ),
		.start_postion(ENABLE_EDIT ? {1'b0, data_num[30:16]} : TRANS_START_POSTION),
		.trans_num (ENABLE_EDIT ? data_num[15:0] : TRANS_MAX_NUM),
		.s_tdata   (s_axis_tdata   ),
		.s_tkeep   (s_axis_tkeep   ),
		.s_tvalid  (s_axis_tvalid  ),
		.s_tready  (s_axis_tready  ),
		.m_tdata   (m_axis_tdata   ),
		.m_tvalid  (valid		   ),
		.m_tready  (ready		   ),
		.m_tlast   (m_axis_tlast   ),
		.m_tkeep   (m_axis_tkeep   )
	);
	
	wire reg_ready;
	wire reg_valid;
	SENDER_AXIS_CCOV u_SENDER_AXIS_CCOV(
		.s_axis_aclk    ( s00_axi_aclk   ),
		.s_axis_aresetn ( s00_axi_aresetn),

		.s_axis_tvalid  (1'b1  ),
		.s_axis_tready  (reg_ready  ),
		.s_axis_tdata   (reg0  ),

		.m_axis_aclk    (axis_aclk    ),
		.m_axis_aresetn (axis_aresetn ),

		.m_axis_tvalid  (reg_valid  ),
		.m_axis_tready  (1'b1     ),
		.m_axis_tdata   (reg0_i   )
	);
	
	always @(posedge s00_axi_aclk or negedge s00_axi_aresetn) begin
		if (!s00_axi_aresetn) begin
			reg0 <= 0;
		end else if(reg_ready)begin
			reg0 <= reg0_o;
		end else begin
			reg0 <= reg0;
		end
	end

	always @(negedge axis_aclk or negedge axis_aresetn) begin
		if (!axis_aresetn) begin
			data_num <= {1'b0, TRANS_START_POSTION[14:0], TRANS_MAX_NUM[15:0]};
		end else if (reg_valid) begin
			data_num <= reg0_i;
		end else begin
			data_num <= data_num;
		end
	end

	endmodule
